﻿using FineUICoreDesigner;
using Newtonsoft.Json.Linq;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
using System.Text.RegularExpressions;

namespace FineUIDesignerVSIX.Handle
{
    public class CoreMVCDesignerHandle : ICoreMVCAfterSave
    {
        /// <summary>
        /// 不生成的标记
        /// </summary>
        public const string NoWebForms = "NoWebForms";

        public void Handle(CoreMVCFileInfo editFileInfo)
        {
            var Content = File.ReadAllText(editFileInfo.ControllerFilePath);
            if (Regex.Match(Content, $"// *{BaseHelp.NoFineUIDesigner}").Success) return;
            if (!BaseHelp.Config.FineUIDesigner) return;
            //生成文件 DesignerFileName DesignerFilePath
            var controlsInfo = ExtractControlsByPages(editFileInfo);
            string designerClassContent = GenerateDesignerClassContent(editFileInfo, controlsInfo);
            if (!string.IsNullOrEmpty(designerClassContent) && controlsInfo.Any())
            {
                BaseHelp.WriteAllText(editFileInfo.DesignerFilePath, designerClassContent);
                BaseHelp.OutputLine($"生成 {editFileInfo.DesignerFileName} 成功 ✏️");
            }
        }

        #region 私有方法

        /// <summary>
        /// 生成文本
        /// </summary>
        /// <param name="editFileInfo"></param>
        /// <param name="controlsInfo"></param>
        /// <returns></returns>
        private string GenerateDesignerClassContent(CoreMVCFileInfo editFileInfo, List<ControlInfo> controlsInfo)
        {
            StringBuilder sb = new StringBuilder();
            sb.AppendLine($"//--------------------------------------------");
            sb.AppendLine($"// 该文件为自动生成，by 没想好");
            sb.AppendLine($"// 注意将 Controller 文件改为 partial class");
            sb.AppendLine($"// 本文件根据 Controller 下所有的 .cshtml文件生成 ");
            sb.AppendLine($"// 如果ID 重复则只生成一个 ");
            sb.AppendLine($"// 如果不想生成 请在 Controller 文件 或 cshtml 文件增加 {BaseHelp.NoFineUIDesigner} 注释 ");
            sb.AppendLine($"// 或者在 appsettings 中添加 FineUIDesigner:false，以防止生成此文件。");
            sb.AppendLine($"// 在 appsettings 中添加 FilterType:[] 用于过滤掉不想生成的类型。");
            sb.AppendLine($"//--------------------------------------------");
            sb.AppendLine($"using FineUICore;");
            sb.AppendLine($"namespace {editFileInfo.NamespaceName}");
            sb.AppendLine("{");
            sb.AppendLine($"   public partial class {editFileInfo.ClassName}");
            sb.AppendLine("   {");

            var controlIDlist = new List<string>();

            foreach (var item in controlsInfo)
            {
                if (!controlIDlist.Contains(item.ID))
                {
                    controlIDlist.Add(item.ID);
                    sb.AppendLine($"        /// <summary>");
                    sb.AppendLine($"        /// {item.PageName}");
                    sb.AppendLine($"        /// </summary>");
                    sb.AppendLine($"        protected FineUICore.{item.Type}AjaxHelper {item.ID} => UIHelper.{item.Type}(\"{item.ID}\");");
                    sb.AppendLine($"");
                }
            }
            sb.AppendLine("   }");
            sb.AppendLine("}");
            return sb.ToString();
        }

        /// <summary>
        /// 找到页面的控件
        /// </summary>
        /// <param name="editFileInfo"></param>
        /// <returns></returns>
        private List<ControlInfo> ExtractControlsByPages(CoreMVCFileInfo editFileInfo)
        {
            var controls = new List<ControlInfo>();
            string[] cshtmlFiles = Directory.GetFiles(editFileInfo.FileRootPath, "*.cshtml");
            var FilterType = GetFilterType(BaseHelp.Appsetting);
            foreach (var item in cshtmlFiles)
            {
                var fileContent = File.ReadAllText(item);
                if (!Regex.Match(fileContent, $"// *{BaseHelp.NoFineUIDesigner}").Success)
                {
                    var pageControls = ExtractControls(fileContent);
                    pageControls.ForEach(control =>
                    {
                        control.PageName = Path.GetFileNameWithoutExtension(item);

                        if (FilterType == null || FilterType.Count == 0 || !FilterType.AsEnumerable().ToList().Contains(control.Type))
                        {
                            controls.Add(control);
                        }
                    });
                }
            }
            return controls;
        }

        /// <summary>
        /// 找到控件和类型的对应
        /// </summary>
        /// <param name="input"></param>
        /// <returns></returns>
        private List<ControlInfo> ExtractControls(string input)
        {
            var controls = new List<ControlInfo>();

            // 正则表达式，用于查找所有的ID
            string idPattern = @"\.ID\(""(?<id>[^""]+)""\)";

            // 查找所有的ID
            var idMatches = Regex.Matches(input, idPattern);

            foreach (Match idMatch in idMatches)
            {
                if (idMatch.Success)
                {
                    // 从当前ID位置向上查找最近的F.开头的控件声明
                    int idStartIndex = idMatch.Index;
                    string inputSubstring = input.Substring(0, idStartIndex);
                    string typePattern = @"F\.(?<type>\w+)\(\)";

                    var typeMatches = Regex.Matches(inputSubstring, typePattern);

                    if (typeMatches.Count > 0)
                    {
                        // 获取最后一个匹配项，即最接近当前ID的控件声明
                        Match lastTypeMatch = typeMatches[typeMatches.Count - 1];
                        controls.Add(new ControlInfo
                        {
                            ID = idMatch.Groups["id"].Value,
                            Type = lastTypeMatch.Groups["type"].Value
                        });
                    }
                }
            }

            return controls;
        }

        /// <summary>
        /// 找到配置项
        /// </summary>
        /// <param name="jsonObject"></param>
        /// <returns></returns>
        private JArray GetFilterType(JObject jsonObject)
        {
            JToken enableWebFormsValue = jsonObject.SelectToken("FineUI.FilterType");
            if (enableWebFormsValue == null)
            {
                return new JArray(); // 如果没有找到EnableWebForms节点，则返回false
            }
            else
            {
                return enableWebFormsValue.Value<JArray>();
            }
        }

        /// <summary>
        /// 页面控件ID
        /// </summary>
        private class ControlInfo
        {
            public string PageName { get; set; }
            public string ID { get; set; }
            public string Type { get; set; }
        }

        #endregion 私有方法
    }
}
